package main

import (
	"context"
	"fmt"
	"golang.org/x/sync/errgroup"
	"io"
	"net/http"
	"os"
	"os/signal"
	"syscall"
)

func helloServer(w http.ResponseWriter, req *http.Request) {
	io.WriteString(w, "hello, world!\n")
}

func startServer(srv *http.Server) error {
	http.HandleFunc("/hello", helloServer)
	fmt.Println("start http server")
	err := srv.ListenAndServe()
	return err
}

func main() {
	g, ctx := errgroup.WithContext(context.Background())
	srv := &http.Server{Addr: ":8080"}

	g.Go(func() error {
		return startServer(srv)
	})

	g.Go(func() error {
		<-ctx.Done()
		fmt.Println("stop http server")
		return srv.Shutdown(ctx)
	})

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

	g.Go(func() error {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ch:
			cancel()
		}
		return nil
	})

	if err := g.Wait(); err == nil {
		fmt.Println("success")
	} else {
		fmt.Println("failed", err)
	}
}
